package com.execdemo.demoorderservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.execdemo.demoorderservice.domain.*;
import com.execdemo.demoorderservice.enumerate.EventEnum;
import com.execdemo.demoorderservice.feign.service.FeignService;
import com.execdemo.demoorderservice.mapper.OrderlistReviewMapper;
import com.execdemo.demoorderservice.service.OrderProductService;
import com.execdemo.demoorderservice.service.OrderlistReviewService;
import com.execdemo.demoorderservice.service.OrderlistService;
import com.execdemo.demoorderservice.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.execdemo.demoorderservice.enumerate.Result;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;

@Slf4j
@Service
public class OrderlistReviewServiceImpl implements OrderlistReviewService {

    @Autowired
    private FeignService feignService;

    @Autowired
    private OrderlistService orderlistService;

    @Autowired
    private OrderlistReviewMapper orderlistReviewMapper;

    @Autowired
    ProductService productService;

    @Autowired
    OrderProductService orderProductService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 订单验证（作废方案）
     *
     * @param orderInfo 订单信息，包含订单详情及关联的产品列表
     */
    @Override
    public void mqConsumer(OrderInfo orderInfo) {
        // 初始化订单产品列表
        List<OrderProduct> orderProductList = new ArrayList<OrderProduct>();
        // 遍历订单中的产品列表，创建订单产品对象，并设置相关属性
        for (Product product : orderInfo.getProductList()) {
            OrderProduct orderProduct = new OrderProduct();
            orderProduct.setpCode(product.getCode());
            orderProduct.setpId(product.getId());
            orderProduct.setoCode(orderInfo.getCode());
//            orderProduct.setoId(orderInfo.getId());
            orderProductList.add(orderProduct);
        }
        // 保存或更新订单产品列表
        orderProductService.saveOrUpdateBatch(orderProductList);

        // 获取订单关联的门店代码，并调用Feign客户端获取门店信息
        String storeCode = orderInfo.getStoreCode();
        Store store = feignService.getStore(storeCode);
        log.info("门店信息 ： " + store);

        // 计算数据库标准数据订单总价
        float reviewPrice = orderlistReviewMapper.countPrice(orderInfo.getCode());
        float lastPrice = reviewPrice;

        // 检查门店承担优惠额度是否足以抵扣订单价格
        if (store.getActiveAccount() <= lastPrice) {
            lastPrice -= store.getActiveAccount();
            log.info("订单：" + orderInfo.getCode() + " 优惠券使用成功");
        } else {
            lastPrice = 0;
            log.info("订单：" + orderInfo.getCode() + " 优惠券超额，免费");
        }

        // 检查订单原始价格、折后价格及门店账户状态，以决定是否添加特定事件代码
        if (reviewPrice != orderInfo.getOriginalPrice() || orderInfo.getDiscountedPrice() != lastPrice || store.getAccountStatus() == 0) {
            String orderEventCode = orderInfo.getOrderEventCode();
            orderEventCode += "001 ";
            orderInfo.setOrderEventCode(orderEventCode);
            log.info("订单：" + orderInfo.getCode() + " 出现 001 事件");
        }

        // 检查订单时间是否在门店营业时间内，以决定是否添加特定事件代码
        if (orderInfo.getTime().isBefore(store.getOpeningTime()) || orderInfo.getTime().isAfter(store.getClosingTime())) {
            String orderEventCode = orderInfo.getOrderEventCode();
            orderEventCode += "002 ";
            orderInfo.setOrderEventCode(orderEventCode);
            log.info("订单：" + orderInfo.getCode() + " 出现 002 事件");
        }


        // 保存订单信息
        orderSave(orderInfo);
    }


    /**
     * 消费者方法，处理订单信息
     * 该方法验证订单总金额，应用优惠券（如果有的话），检查订单价格和时间是否符合预期，
     * 并根据验证结果发送相应的消息到消息队列
     *
     * @param orderInfo 订单信息对象，包含订单详情，如产品列表，订单代码，原始价格，折扣后价格等
     */
    @Override
    public void mqConsumer2(OrderInfo orderInfo) {

        log.info("订单：" + orderInfo.getCode() + " 开始验证");
        String orderCode = orderInfo.getCode();

        // 获取订单中的产品列表
        List<Product> productList = orderInfo.getProductList();
        // 验证订单总金额
        float totalAmount = productService.verifyTheTotalAmount(productList);
        float lastPrice = totalAmount;
        log.info("订单：" + orderCode + " 订单总金额：" + totalAmount);

        // 获取订单关联的门店代码
        String storeCode = orderInfo.getStoreCode();
        // 通过Feign客户端获取门店信息
        Store store = feignService.getStore(storeCode);
        log.info("门店信息 ： " + store);

        // 检查应用优惠券后价格
        if (store.getActiveAccount() <= lastPrice) {
            lastPrice -= store.getActiveAccount();
            log.info("订单：" + orderCode + " 优惠券已使用,折后价为："+ lastPrice);
        } else {
            lastPrice = 0;
            log.info("订单：" + orderCode + " 优惠券超额，免费");
        }

        // 验证订单价格是否正确，以及门店优惠券状态
        if (totalAmount != orderInfo.getOriginalPrice() || orderInfo.getDiscountedPrice() != lastPrice || store.getAccountStatus() == 0) {
            log.info("订单：" + orderCode + " 出现 001 事件");
            String jsonString = JSONObject.toJSONString(Result.build(orderInfo, EventEnum.ORDER_PRICE_ERROR));
            rabbitTemplate.convertAndSend("", "mqback", jsonString);
            return;
        }

        // 检查订单时间是否在门店营业时间内
        if (orderInfo.getTime().isBefore(store.getOpeningTime()) || orderInfo.getTime().isAfter(store.getClosingTime())) {
            log.info("订单：" + orderCode + " 出现 002 事件");
            String jsonString = JSONObject.toJSONString(Result.build(orderInfo, EventEnum.ORDER_TIME_ERROR2));
            rabbitTemplate.convertAndSend("", "mqback", jsonString);
            return;
        }




        QueryWrapper<Orderlist> wrapper = new QueryWrapper<>();
        wrapper.eq("code", orderCode);
        // 创建一个新的Orderlist对象
        Orderlist orderlist = orderlistService.getOne(wrapper);
        if (orderlist == null) {

            // 尝试保存订单信息和订单产品信息
            Orderlist orderedSave = orderSave(orderInfo);
            Boolean orderProductSave = orderProductSave(productList,orderedSave);

            // 根据保存结果发送消息到消息队列
            if (orderedSave != null && orderProductSave) {
                String jsonString = JSONObject.toJSONString(Result.ok(orderInfo));
                rabbitTemplate.convertAndSend("", "mqback", jsonString);

            } else {
                String jsonString = JSONObject.toJSONString(Result.fail(orderInfo));
                rabbitTemplate.convertAndSend("", "mqback", jsonString);

            }
            return;
        } else {

            // 尝试保存订单信息和订单产品信息
            Boolean orderUpdate = orderUpdate(orderInfo, orderlist);
            // 根据保存结果发送消息到消息队列
            if (orderUpdate) {
                log.info("订单配送状态：" + orderlist.getDeliveryStatus());
                String jsonString = JSONObject.toJSONString(Result.ok(orderInfo));
                rabbitTemplate.convertAndSend("", "mqback", jsonString);

            } else {
                String jsonString = JSONObject.toJSONString(Result.fail(orderInfo));
                rabbitTemplate.convertAndSend("", "mqback", jsonString);

            }
            return;
        }

    }


    /**
     * 保存订单信息
     * <p>
     * 该方法将OrderInfo对象中的信息转换到Orderlist对象中，并调用orderlistService的save方法进行保存
     * 主要用于订单信息的持久化
     *
     * @param orderInfo 订单信息对象，包含订单的详细信息
     * @return Boolean 表示订单保存是否成功
     */
    private Orderlist orderSave(OrderInfo orderInfo) {
        // 日志记录器
        Logger logger = LoggerFactory.getLogger(this.getClass());

        Orderlist orderlist = new Orderlist();

        // 非空校验
        if (orderInfo == null) {
            logger.error("orderInfo is null");
            return orderlist;
        }

        try {

            // 使用BeanUtils简化属性复制
            BeanUtils.copyProperties(orderlist , orderInfo);

            // 调用orderlistService的save方法保存订单信息
            boolean save = orderlistService.save(orderlist);

            // 返回保存结果
            if (save) {
                logger.info("订单保存成功，订单号 : {}", orderInfo.getCode());
            } else {
                logger.warn("订单保存失败，订单号 : {}", orderInfo.getCode());
            }
            return orderlist;
        } catch (Exception e) {
            logger.error("Error occurred while saving order: {}", e.getMessage(), e);
            return orderlist;
        }
    }


    private Boolean orderUpdate(OrderInfo orderInfo, Orderlist orderlist) {
        // 日志记录器
        Logger logger = LoggerFactory.getLogger(this.getClass());

        // 非空校验
        if (orderInfo == null) {
            logger.error("orderInfo is null");
            return false;
        }

        try {

            // 使用BeanUtils简化属性复制
            BeanUtils.copyProperties(orderlist, orderInfo);

            // 调用orderlistService的save方法保存订单信息
            boolean updated = orderlistService.updateById(orderlist);

            // 返回保存结果
            if (updated) {
                logger.info("订单保存成功，订单号 : {}", orderInfo.getCode());
            } else {
                logger.warn("订单保存失败，订单号 : {}", orderInfo.getCode());
            }
            return updated;
        } catch (Exception e) {
            logger.error("Error occurred while saving order: {}", e.getMessage(), e);
            return false;
        }
    }


    /**
     * 保存订单产品关联信息
     * 此方法将产品列表与订单信息关联，并批量保存到订单产品表中
     *
     * @param productList 与订单关联的产品列表
     * @param orderlist   订单信息，包括订单代码和ID
     * @return 返回批量保存操作是否成功
     */
    private boolean orderProductSave(List<Product> productList,Orderlist orderlist) {
        // 日志记录器
        Logger logger = LoggerFactory.getLogger(this.getClass());


        // 输入参数校验
        if (productList == null || orderlist == null) {
            logger.error("Input parameters cannot be null.");
            return false;
        }

        // 创建一个空的订单产品列表，用于存储即将保存的订单产品信息
        List<OrderProduct> orderProductList = new ArrayList<>();

        // 遍历产品列表，为每个产品创建一个对应的订单产品对象
        for (Product product : productList) {
            OrderProduct orderProduct = new OrderProduct();
            // 设置产品代码
            orderProduct.setpCode(product.getCode());
            // 设置产品ID
            orderProduct.setpId(product.getId());
            // 设置订单代码
            orderProduct.setoCode(orderlist.getCode());
            // 设置订单ID
            orderProduct.setoId(orderlist.getId());
            // 将初始化完毕的订单产品对象添加到列表中
            orderProductList.add(orderProduct);
        }

        try {
            // 调用服务层方法，批量保存订单产品列表
            boolean saved = orderProductService.saveBatch(orderProductList);
            logger.info("Batch save operation completed with result: {}", saved);
            return saved;
        } catch (Exception e) {
            logger.error("Error occurred during batch save operation.", e);
            return false;
        }
    }

}
